#include <fstream>
#include <iostream>
#include <vector>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include "aprioriall.cpp"


inline int string2int(std::string s)
{
	std::istringstream strin(s);
	int i;
	strin >> i;
	return i;
}

inline std::string int2string(int n)
{
	std::stringstream ss;
	std::string temp;
	ss << n;
	ss >> temp;
	return temp;
}

vector<sequence> parsefile(std::string filename){
	char ch, ch1='?';
    string content = "", contentx= "", contenty= "", contentt= "";		  //<x,y,t>
	sequencenode record;												  //object predefined
	sequence* transaction = new sequence();
    vector<sequence> db;
    int lasttimestamp = -1;
	ifstream inFile(filename.c_str(), ios::in);
	sequencenode* lastnode = new sequencenode();
	if (!inFile)
	{
		cerr << "File could not be opened" << endl;
		exit(1);
	}
    while (inFile.get(ch))
    {
		switch(ch)
		{
			case '<' :
				ch1 = '<';
				contentx = "";
				break;
			case ',' :
				if (ch1 == ',')
				{
					ch1 = '*';
					contentt = "";
				}
				else
				{
					ch1 = ',';
					contenty = "";
				}
				break;
			case '>':
				ch1 = '>';
				break;
			case '|' :
				ch1 = '|';
				break;
			case '?' :
				ch1 = '?';
			    transaction->addSequenceNode(*lastnode);
               // cout<<transaction->tostring()<<endl;
                db.push_back(*transaction);
				transaction = new sequence();									  //clear the content of the sequence avoid new a sequence continuously
				content = "";
                lasttimestamp = -1;
				break;
		}

		if ((ch1 == '?') && (ch != '?'))
		{
			content +=ch;												  //tid of the sequence is the index of the database
		}

		if ((ch1 == '<') && (ch != '<'))
		{
			contentx +=ch;
		}

		if ((ch1 == ',') && (ch != ','))
		{
			contenty +=ch;
		}

		if ((ch1 == '*') && (ch != ','))
		{
			contentt +=ch;
		}

		//add SequenceNode in a Sequence, contentx and contty represent the specific coordinates of a location item
		if (ch == '>')	//
		{
			int x = string2int(contentx);						    //fill the data into the object of x
			int y = string2int(contenty);						    //fill the data into the object	of y
			int currentTimestamp = string2int(contentt);					    //fill the data into the object

			sequencenode* node = new sequencenode(x, y, -1);
			if (lasttimestamp==-1){
                  lastnode = node;
                  lasttimestamp = currentTimestamp;
            }else {
                 // cout<<currentTimestamp<<","<<lasttimestamp<<endl;
                  lastnode->t = currentTimestamp-lasttimestamp;
                  transaction->addSequenceNode(*lastnode);
                  lastnode = node;
                  lasttimestamp = currentTimestamp;
            }
		}
    }
	cout<<int2string(db.size())<<endl;
	inFile.close();
	return db;

}

int main(int argc, char* argv[]){
  //  cout<<p<<endl;
    string filename = argv[1];
     int sup = string2int(argv[2]);
     int gap = string2int(argv[3]);
     int grid = string2int(argv[4]);
     int bucket = string2int(argv[5]);
     cout<< "filename:"<<filename<<endl;
     cout<< "support:"<<sup<<endl;
     cout<<"gap:"<<gap<<endl;
     cout<< "grid:"<<grid<<endl;
     cout<<"bucket:"<<bucket<<endl;
     timeval start, end;
     gettimeofday(&start, 0);
    vector<sequence> seqs = parsefile(filename);
    aprioriAll* aal = new aprioriAll();
    aal->init(seqs, gap, sup,grid,bucket);
    aal->mining();
    gettimeofday(&end, 0);
    cout << "Number of tuples candidates:" << aal->candidates << endl;
    cout <<"Number of tuples scanned:" << aal->tuplesScanned << endl;
//    double totalTime = (double)(end-begin/CLOCKS_PER_SEC);

    cout << "total time consumed is:"<<(end.tv_sec -start.tv_sec + (double)(end.tv_usec - start.tv_usec)/CLOCKS_PER_SEC)<<endl;
    //system("pause");
    return 0;
}
